﻿using System.IO;
using System.Xml.Serialization;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using TShooter.TfsWord.Xml;

namespace TShooter.TfsWord.TeamFoundation
{
    [XmlRoot("WorkItemData", Namespace = Consts.XmlNamespace)]
    public class WorkItemData
    {
        #region Constructors and member variables

        private static XmlSerializer _Serializer;
        private WorkItemFieldDataCollection _Fields = new WorkItemFieldDataCollection();

        public WorkItemData()
        {
        }

        internal WorkItemData(WorkItem baseWorkItem)
            : this(baseWorkItem.Type)
        {
            LoadValues(baseWorkItem);
        }

        internal WorkItemData(WorkItemType baseWorkItemType)
        {
            LoadDefinition(baseWorkItemType);
        }

        #endregion

        #region Properties

        public WorkItemFieldData this[string referenceName]
        {
            get { return Fields[referenceName]; }
        }

        [XmlArray("Fields")]
        [XmlArrayItem("Field", typeof (WorkItemFieldData))]
        public WorkItemFieldDataCollection Fields
        {
            get { return _Fields; }
        }

        public int Id { get; set; }

        public int Revision { get; set; }

        public string WorkItemType { get; set; }

        private static XmlSerializer Serializer
        {
            get { return _Serializer ?? (_Serializer = new XmlSerializer(typeof (WorkItemData))); }
        }

        #endregion

        public override string ToString()
        {
            var sw = new StringWriter();
            Serializer.Serialize(sw, this);

            return sw.ToString();
        }

        private void LoadValues(WorkItem baseWorkItem)
        {
            foreach (var field in Fields)
            {
                field.Value = baseWorkItem[field.ReferenceName];
            }
        }

        private void LoadDefinition(WorkItemType baseWorkItemType)
        {
            foreach (FieldDefinition fld in baseWorkItemType.FieldDefinitions)
            {
                Fields.Add(new WorkItemFieldData
                               {
                                   AllowedValues = new AllowedValuesCollection(fld.AllowedValues),
                                   CanSortBy = fld.CanSortBy,
                                   FieldType = (FieldType) fld.FieldType,
                                   HelpText = fld.HelpText,
                                   Id = fld.Id,
                                   IsComputed = fld.IsComputed,
                                   IsEditable = fld.IsEditable,
                                   IsIndexed = fld.IsIndexed,
                                   IsQueryable = fld.IsQueryable,
                                   Name = fld.Name,
                                   ReferenceName = fld.ReferenceName,
                                   ReportingType = (ReportingType) fld.ReportingAttributes.Type,
                                   Usage = (FieldUsages) fld.Usage
                               });
            }
        }
    }
}